<!-- 
 * @Description: 菜单管理
 * @Author: huguodong 
 * @Date: 2023-12-15 15:43:08
!-->
<template>
  <div class="table-box">
    <ProTable ref="proTable" title="菜单列表" :indent="20" :columns="columns" :request-api="menuApi.tree" :pagination="false">
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <s-button suffix="菜单" @click="onOpen(FormOptEnum.ADD)" />
        <s-button
          suffix="菜单"
          :opt="FormOptEnum.DELETE"
          plain
          :disabled="!scope.isSelected"
          @click="onDelete(scope.selectedListIds, '删除所选菜单')"
        />
      </template>
      <!-- 表格 菜单类型 按钮 -->
      <template #menuType="scope">
        <el-space>
          <el-tag>{{ dictStore.dictTranslation(SysDictEnum.MENU_TYPE, scope.row.menuType) }}</el-tag>
          <el-tag v-if="scope.row.isHome === true" type="warning">首页</el-tag>
        </el-space>
      </template>
      <!-- 状态 -->
      <template #status="scope">
        <el-tag v-if="scope.row.status === CommonStatusEnum.ENABLE" type="success">{{
          dictStore.dictTranslation(SysDictEnum.COMMON_STATUS, scope.row.status)
        }}</el-tag>
        <el-tag v-else type="danger">{{ dictStore.dictTranslation(SysDictEnum.COMMON_STATUS, scope.row.status) }}</el-tag>
      </template>
      <!-- 操作 -->
      <template #operation="scope">
        <el-space>
          <s-button link :opt="FormOptEnum.EDIT" @click="onOpen(FormOptEnum.EDIT, scope.row)" />
          <s-button link :opt="FormOptEnum.DELETE" @click="onDelete([scope.row.id], `删除【${scope.row.title}】菜单`)" />
          <el-dropdown @command="handleCommand">
            <el-link type="primary" :underline="false" :icon="ArrowDown"> 更多 </el-link>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-if="scope.row.parentId === 0" :command="command(scope.row, cmdEnum.ChangeModule)">{{
                  cmdEnum.ChangeModule
                }}</el-dropdown-item>
                <el-dropdown-item v-if="isMenu(scope.row.menuType)" :command="command(scope.row, cmdEnum.Button)">{{
                  cmdEnum.Button
                }}</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </el-space>
      </template>
    </ProTable>
    <!-- 新增/编辑表单 -->
    <Form ref="formRef" />
    <!-- 更改模块 -->
    <ChangeModule ref="changeModuleFormRef" />
    <!-- 权限按钮 -->
    <Button ref="buttonFormRef" />
  </div>
</template>

<script setup lang="tsx" name="sysMenu">
import { menuApi, Menu } from "@/api";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import { ArrowDown } from "@element-plus/icons-vue";
import { useUserStore, useDictStore } from "@/stores/modules";
import { SysDictEnum, FormOptEnum, MenuTypeDictEnum, CommonStatusEnum } from "@/enums";
import Form from "./components/form.vue";
import { useHandleData } from "@/hooks/useHandleData";
import ChangeModule from "./components/changeModule.vue";
import Button from "../button/index.vue";

const userStore = useUserStore();
const dictStore = useDictStore();
//遍历模块列表，生成下拉选项
const moduleOptions = userStore.moduleList.map(item => {
  return { label: item.title, value: item.id };
});
// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const proTable = ref<ProTableInstance>();
// 表格配置项
const columns: ColumnProps<Menu.MenuInfo>[] = [
  { type: "selection", fixed: "left", width: 50 },
  { prop: "id", label: "Id", isShow: false },
  {
    prop: "module",
    label: "应用模块",
    enum: moduleOptions,
    search: {
      el: "select",
      props: {
        clearable: false,
        placeholder: "请选择应用模块"
      },
      defaultValue: moduleOptions[0].value
    },
    isShow: false
  },
  { prop: "title", label: "菜单名称", width: 150, align: "left", search: { el: "input" } },
  {
    prop: "icon",
    label: "菜单图标",
    render: scope => {
      return <svg-icon icon={scope.row.icon} class="h-6 w-6" />;
    }
  },
  { prop: "menuType", label: "菜单类型" },
  { prop: "name", label: "组件名称" },
  { prop: "path", label: "路由地址", width: 200, search: { el: "input" } },
  { prop: "component", label: "组件路径", width: 250 },
  { prop: "sortCode", label: "排序", width: 80 },
  { prop: "status", label: "状态" },
  { prop: "description", label: "说明" },

  { prop: "operation", label: "操作", width: 230, fixed: "right" }
];

// 表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);

/**
 * 打开表单
 * @param opt  操作类型
 * @param record  记录
 */
function onOpen(opt: FormOptEnum, record: {} | Menu.MenuInfo = {}) {
  formRef.value?.onOpen(
    {
      opt: opt,
      record: record,
      successful: () => RefreshTable()
    },
    proTable.value?.searchParam.module
  );
}

/**
 * 删除
 * @param ids  id数组
 */
async function onDelete(ids: string[], msg: string) {
  // 二次确认 => 请求api => 刷新表格
  await useHandleData(menuApi.delete, { ids }, msg);
  RefreshTable();
}
/**
 * 刷新表格
 */
function RefreshTable() {
  proTable.value?.refresh();
}

/**判断是否是菜单 */
const isMenu = computed(() => (menuType: string) => {
  return menuType === MenuTypeDictEnum.MENU;
}); //是否是菜单

/** 更多下拉菜单命令枚举 */
enum cmdEnum {
  ChangeModule = "更改模块",
  Button = "权限按钮"
}

/** 下拉菜单参数接口 */
interface Command {
  row: Menu.MenuInfo;
  command: cmdEnum;
}

/**配置command的参数 */
function command(row: Menu.MenuInfo, command: cmdEnum): Command {
  return {
    row: row,
    command: command
  };
}

// 修改模块表单引用
const changeModuleFormRef = ref<InstanceType<typeof ChangeModule> | null>(null);
// 权限按钮表单引用
const buttonFormRef = ref<InstanceType<typeof Button> | null>(null);

/**
 * 更多下拉菜单点击事件
 * @param command
 */
function handleCommand(command: Command) {
  switch (command.command) {
    case cmdEnum.ChangeModule:
      //更改模块
      changeModuleFormRef.value?.onOpen({
        moduleOptions,
        id: command.row.id,
        title: command.row.title,
        module: command.row.module,
        successful: () => RefreshTable()
      });
      break;
    case cmdEnum.Button:
      //权限按钮
      buttonFormRef.value?.onOpenTable(command.row.id);
      break;
  }
}
</script>

<style lang="scss" scoped>
.el-dropdown-link {
  display: flex;
  align-items: center;
  color: var(--el-color-primary);
  cursor: pointer;
}
:deep(.el-link__inner) {
  padding-left: 6px !important;
}
</style>
